var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path')
  , userDB = require('./models/user')
  , zoneDB = require('./models/zone')
  , parcelleDB = require('./models/parcelle')
  , buildingDB = require('./models/building')
  , cropDB = require('./models/crops')
  , mongoose = require('mongoose')
  , md5 = require('MD5')
  , map = require('./routes/map')
  , difficulty = require('./routes/difficulty')
  , connect = require('connect')
  , adm = require('./routes/admin')
  , setDB = require ('./models/settings')
  , all = require('./routes/alliance')
  , allia = require('./models/alliance')
    , invA = require('./models/invitation_alliance');

var cookieParser = express.cookieParser('modafuckasecret')
    , sessionStore = new connect.middleware.session.MemoryStore();

var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(cookieParser);
app.use(express.session({ store: sessionStore }));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
app.configure(function(){
    app.use(function(req, res, next){
        res.locals.user = req.session.user;
        next();
    });
});

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

function restrict(req, res, next) {
    if (req.session.user) {
        console.log('restrictok');
        next();
    } else {
        res.redirect('/');
    }
}

function restrictAdmin(req, res, next) {
    if (req.session.user && req.session.user.isAdmin == true) {
        next();
    } else {
        res.redirect('/');
    }
}


httpServer = http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port') );
    mongoose.connect('mongodb://localhost/blog');
    testzone();
    testSettings();
});

var io = require('socket.io').listen(httpServer);
var maMap = [];
var mySettings;
var SessionSockets = require('session.socket.io')
    , sessionSockets = new SessionSockets(io, sessionStore, cookieParser);

app.get('/', routes.index);
app.get('/users',restrict , user.list);
app.get('/map',restrict, map.mapP);
app.get('/difficulty',restrict , difficulty.dif);
app.get('/admin', restrictAdmin, adm.adminContent);
app.get('/alliance', restrict, all.all);


sessionSockets.on('connection', function(err, socket, session){
    console.log(maMap.length);
    socket.emit('session', session);

    console.log(err);
    var pass = "";
    var mail = "";

    socket.on('login', function(user){
        console.log('logging in');
        pass = md5(user.password);
        mail = user.mail;

        //mongoose.connect('mongodb://localhost/blog');
        userDB.User.findOne({ mail: user.mail }, function (err, usr){
            //mongoose.connection.close();
            if(usr != null){
                if(mail == usr.mail && pass == usr.password){
                    if(usr.isCreated == true){
                        session.user = usr;
                        session.save();
                        socket.emit('logged');
                    }else{
                        session.user = usr;
                        session.save()
                        socket.emit('newGame');
                    }
                }else{
                    socket.emit('wrongLogin');
                }
            }else{
                socket.emit('wrongLogin');
            }
        });
    });
    socket.on('inGame', function(){
        setLvlUser(session.user.mail);
        socket.emit('sendMap', maMap);
        socket.broadcast.emit('sendMap', maMap);
        socket.emit('user', session.user);
        console.log("MAP ENVOYEE")
    })

    socket.on('registration', function(user){
        if(user.mail != "" || user.password != "" || user.passwordverif != ""){
            console.log('register non nul');
            if ( user.password == user.passwordverif ){
                  pass = md5(user.password);
                  mail = user.mail;

                //mongoose.connect('mongodb://localhost/blog');
                var u = new userDB.User();
                u.mail = mail;
                u.password = pass;
                if(user.admin == "oui"){
                    u.isAdmin = true;
                }
                userDB.User.findOne({ mail: user.mail }, function (err, usr){
                        if(usr == null ){
                            u.save(function (err) {
                                if (err) { throw err; }
                                socket.emit('registerSuccess');
                                //mongoose.connection.close();
                            });
                        }else if(usr != null){
                            socket.emit('mailUsed');
                            //mongoose.connection.close();
                        }
                });
            }
        }else{
            socket.emit('registerNull');
        }
    });

    socket.on('invitPlayer', function(player){
       invA.AllianceInvitation.findOne({name_invited: player.pName, alliance_name: session.user.allianceName}, function(err, inv){
           if(err){throw err;}
           if(inv == null){
               var i = new invA.AllianceInvitation();
               i.alliance_name = session.user.allianceName;
               i.name_invited = player.pName;

               i.save(function(err){
                   if(err){throw err; }
                   socket.emit('invitOK');
               })
           }else{
               socket.emit('playerAlreadyInvit')
           }
       })

    })

    socket.on('requestParcelles', function(user){
        var TabBuilding = [];
        var TabCrop = [];
        parcelleDB.Parcelle.find( {zone_id : user.zone_id}, function (err, zon){
            if(err){throw err;}
            if(zon.length == 0){
                console.log("tape dans le fond, je suis pas ta mère");
                //mongoose.connection.close();
            }else
            {
                if(user.zone_user == session.user.mail){
                for(var i = 0; i<zon.length;i++){
                    buildingDB.Building.findOne( {parcelle_id : zon[i]._id}, function(err, Building){
                        if(Building != null){
                        TabBuilding.push(Building);
                        socket.emit('setBuilding', Building);
                            console.log('envoi des building');
                        }
                    })
                }

                for(var i = 0; i<zon.length;i++){
                    cropDB.Crops.findOne( {parcelle_id : zon[i]._id}, function(err, Crop){
                        if(Crop!=null){
                        TabCrop.push(Crop);
                        socket.emit('setCrop', Crop);
                            console.log('envoi des crop');
                        }
                    })
                }

                socket.emit("sendParcelles", zon);
                }else{
                    console.log("Ca n'est pas la bonne parcelle");
                }
            }
        });
        //mongoose.connection.close();
        console.log(user.zone_id);
    })
    socket.on('disconnected', function(){
        session.destroy();
        socket.disconnect();
        console.log('socket fermé');
    });
    socket.on('sendBuilding',function(data){
        if(data!=null){
            var newBuilding = new buildingDB.Building();
            newBuilding.name = data.name;
            newBuilding.price = data.price;
            newBuilding.power= data.power;
            newBuilding.whitering = data.whitering;
            newBuilding.capacityMax = data.capacity;
            newBuilding.parcelle_id = data.parcelle_id;
            newBuilding.i=data.i;
            newBuilding.j=data.j;
            newBuilding.save(function(err){
                if(err) { throw err;console.log(err); }
                console.log('Building ajouter avec succès !');
                //mongoose.connection.close();
            });
        }
    });
	    socket.on('createAlliance', function(myAlli){
        allia.Alliance.findOne({name: myAlli.allName}, function(err, myA){
           if(myA == null){
            var a = new allia.Alliance();
            a.name = myAlli.allName;
            a.level = session.user.level;
            a.owner = session.user.mail;
            a.save(function(err){
                if(err){ throw err; }
                userDB.User.findOne({mail: session.user.mail}, function(err, u){
                     if(err){ throw err;}
                     u.allianceName = myAlli.allName;
                     u.save(function(err){
                        if(err){throw err;}
                         session.user.allianceName = myAlli.allName;
                         session.save();
                         socket.emit('allianceCreatingOK');
                    })
                })
            })
           }else{
               socket.emit('allianceNameAlreadyTaken');
           }
        })
    });
	    socket.on('ragequitAlli', function(){
         allia.Alliance.findOne({owner: session.user.mail}, function(err,myA){
             if(myA == null){
                 userDB.User.findOne({mail: session.user.mail}, function(err, u){
                     if(err){throw err;}
                     u.allianceName = "";
                     u.save(function(err){
                         if(err){throw err;}
                         session.user.allianceName = null;
                         session.save();
                         socket.emit('ragequitok');
                     })
                 })
             }else{
                 userDB.User.findOne({mail: session.user.mail}, function(err, u){
                     if(err){throw err;}
                     u.allianceName="";
                     userDB.User.update({ allianceName: session.user.allianceName}, { allianceName: ""}, function(err){
                               if(err){throw err;}
                             u.save(function(err){
                                 if(err){throw err;}
                                 session.user.allianceName = null;
                                 session.save();
                                 allia.Alliance.remove({owner: session.user.mail}, function(err){
                                     if(err){throw err;}
                                     socket.emit('ragequitok');
                                 })
                             })
                         })
                 })
             }
         })
    })

    socket.on('requestSettings', function(){
        socket.emit('giveSettings', mySettings);
    });

    socket.on('suprInvit', function(usr){
        invA.AllianceInvitation.remove({name_invited: usr.usr, alliance_name: session.user.allianceName}, function(err){
            if(err){ throw err;}
            socket.emit('suprInvitOK');
        })
    });

    socket.on('requestInvit', function(){
        invA.AllianceInvitation.find({alliance_name: session.user.allianceName}, function(err, inv){
            if(err){throw err;}
            socket.emit('youInvit', inv);
        });
    });

    socket.on('requestInvitPlayer', function(){
        invA.AllianceInvitation.find({name_invited: session.user.mail}, function(err, inv){
            if(err){throw err;}
            socket.emit('sendInvitPlayer', inv);

        })
    })

    socket.on('isAlliOwner', function(){
        var ad = false;
       allia.Alliance.findOne({ owner: session.user.mail }, function(err, alli){
           if(err){throw err;}
           if(alli != null){
               if(alli.owner == session.user.mail){
                   ad = true;
               }
               socket.emit('isAlliOwnerRespond', ad);
           }
       })
    });

    socket.on('modifySettings', function(settings){

        setDB.Settings.findOne({}, function (err, set){
            if(err){ throw err;}
            if(set  != null){
                set.money = settings.money;
                set.weapon1 = settings.w1;
                set.weapon2 = settings.w2;
                set.weapon3 = settings.w3;
                set.weapon4 = settings.w4;
                set.save(function(err){
                    if(err){throw err;}
                    socket.emit('modifySettingsSuccess');
                })
            }
        })
    });

    socket.on('refInvit', function(allName){
       invA.AllianceInvitation.remove({name_invited : session.user.mail, alliance_name: allName.allN}, function(err){
           if(err){throw err;}
           socket.emit('refInvitOK');
       })
    });

    socket.on('accInvit', function(allName){
        session.user.allianceName = allName.allN;
        session.save();
         userDB.User.update({mail: session.user.mail}, {allianceName: allName.allN}, function(err){
             if(err){ throw err;}
             invA.AllianceInvitation.remove({name_invited : session.user.mail},{ alliance_name: allName.allN}, function(err){
                 if(err){throw err;}

             })
         })
        socket.emit('accInvitOK');
    });


    socket.on('cronCrop', function(data){
        cropDB.Crops.update({parcelle_id:data.parcelle_id},{decay_date : data.decay_date}, function(err){});

    });
    socket.on('cronParcelle', function(data){
        parcelleDB.Parcelle.update({_id:data._id},{maturity_level : data.maturity_level, humidity : data.humidity, healthy_level: data.healthy_level}, function(err){});
    });
    socket.on('sendCrop', function(data){
        if(data!=null){
            var newCrop = new cropDB.Crops();
            newCrop.type= data.type;
            newCrop.price=data.price;
            newCrop.productivity=data.productivity;
            newCrop.decay_date=data.decay_date;
            newCrop.maturation_date =data.maturation_date;
            newCrop.decay_time = data.decay_date;
            newCrop.parcelle_id = data.parcelle_id;
            newCrop.i=data.i;
            newCrop.j=data.j;
            newCrop.save(function(err){
                if(err) { throw err;console.log(err); }
                console.log('Crop ajouter avec succés !');
                //mongoose.connection.close();
            });
        }
    });
    socket.on('difficult', function(user){
        var tabZone = [];
        var i;
        var zoneID;
        var m = 0;
        console.log(user.niveau);
        console.log(session.mail);
        //mongoose.connect('mongodb://localhost/blog');
        zoneDB.Zone.find({user_mail: ""}, function(err, zones){
             tabZone = zones;
             console.log(tabZone.length);
             i = Math.floor((Math.random()*tabZone.length)+1);
            console.log(i);
            zoneID = tabZone[i]._id;
            console.log(zoneID);
            zoneDB.Zone.findOne({_id: zoneID}, function(err, zone){
                console.log(zoneID)
                console.log(zone._id);
                console.log(zone);
                zone.user_mail = session.user.mail;
                zone.save(function(err){
                    if(err) { throw err;console.log(err); }
                    console.log('ZONE MODIDIER AVEX SUCCES !');
                    //mongoose.connection.close();
                });
            })
        });
            setDB.Settings.findOne({}, function (err, set){
                if(err){ throw err;}
                console.log(set);
                m = set.money;
            });


        userDB.User.findOne({ mail: session.user.mail }, function (err, usr){
            session.user.isCreated = true;
            usr.isCreated = true;
            switch(user.niveau){
                case 'easy':
                    usr.money = m;
                    session.user.money = m;
                    break;
                case 'medium':
                    usr.money = m/2;
                    session.user.money = m/2;
                    break;
                case 'hard':
                    usr.money = m/5;
                    session.user.money = m/5;
                    break;
            }
            session.save();
            usr.save(function (err) {
                if (err) { throw err; }
                for(var i = 0; i<100;i++){
                    var Parcelle= new parcelleDB.Parcelle();
                    Parcelle.zone_id = zoneID;
                    Parcelle.healthy_level = 200;
                    Parcelle.humidity = Math.floor((Math.random()*80)+10);
                    if(i<=20){
                        Parcelle.fertility = Math.floor((Math.random()*20)+1)+80;
                    }
                    if(i>20 && i<=40 ){
                        Parcelle.fertility = Math.floor((Math.random()*20)+1)+60;
                    }
                    if(i>40 && i<=60){
                        Parcelle.fertility = Math.floor((Math.random()*20)+1)+40;
                    }
                    if(i>60 && i<=80){
                        Parcelle.fertility = Math.floor((Math.random()*20)+1);
                    }
                    if(i>80 && i<=100){
                        Parcelle.fertility = Math.floor((Math.random()*20)+1)+80;
                    }
                    Parcelle.save(function(err){
                        if(err) { throw err; }
                        console.log('utilisateur modifié avec succès !');
                        //mongoose.connection.close();
                            testzone();
                    })
                }
                socket.emit('logged');
            });
        });
    });
});
function testzone(){
    console.log("Je passe dans la fct");
    //mongoose.connect('mongodb://localhost/blog');
    console.log("J'ai fait ma requete");
    zoneDB.Zone.find({}, function(err, zon){
        console.log("je suis entrée dans le base")
        if(err){ throw err;}
        if(zon.length != 0){
            //mongoose.connection.close();
            maMap = zon;
            console.log(maMap);
        }else{
            console.log("Je créer la map");
            for( var i = 0; i<5; i++){
                for ( var j = 0; j<10; j++){
                    var zo = new zoneDB.Zone();
                    zo.xPos = i;
                    zo.yPos = j;
                    zo.save(function(err){
                        if(err) { throw err;console.log(err); }
                        //mongoose.connection.close();
                    })
                    maMap.push(zo);
                }
            }
        }
    })
    console.log("ok, j'ai finis");

}
function testSettings(){
    setDB.Settings.findOne({}, function (err, set){
        if(err){ throw err;}
        if(set  != null){
          mySettings = set;
        }else{
            var s = new setDB.Settings();
            s.save(function(err){
                if(err){throw err;}
            })
            mySettings = s;
        }
    })
};


function setLvlUser(user){
    var con = 0;
    zoneDB.Zone.find({user_mail: user}, function(err, zon){
        if(err){throw err;}
        userDB.User.findOne({mail: user}, function(err, usr){
            if(err){throw err;}
                usr.level = zon.length;
                usr.save(function(err){
                    if(err){throw err;}
            })
        })
    })
};

function setLvlAlliance(){
    allia.Alliance.find({}, function (err, alli){
        if(err){throw err;}
        for(var i = 0; i<alli.length; i++){
          userDB.User.find({allianceName: alli[i].name})
        }
    })
}

